package app.server.project.main.service.db.entity.user;

import app.server.project.core.constants.Def;
import app.server.project.core.syndb.SynDBMgr;
import app.server.project.core.util.MathUtil;
import app.server.project.core.util.SysTimeUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Transient;
import lombok.Data;
import org.hibernate.annotations.Comment;

import java.time.LocalDateTime;
import java.util.Date;

@Data
@Entity(name = "user_energy")
@TableName("user_energy")
@Comment(value = "用户基本信息表")
public class UserEnergyEntity {

    @Id
    @Column(name = "user_id")
    @Comment("用户主键")
    @TableId("user_id")
    private long userId;

    @TableField("init")
    @Comment("初始化体力")
    @Column(name = "init")
    private int init;

    @TableField("max_num")
    @Comment("最大体力值")
    @Column(name = "max_num")
    private long maxNum;

    @TableField("flush_time")
    @Comment("体力值刷新时间")
    @Column(name = "flush_time")
    private long flushTime;

    @TableField("create_time")
    @Comment("创建时间")
    @Column(name = "create_time")
    private LocalDateTime createTime;


    @TableField("draw_time")
    @Comment("领取时间")
    @Column(name = "draw_time")
    private long drawTime;

    @TableField("draw_num")
    @Comment("连续领取次数")
    @Column(name = "draw_num")
    private long drawNum;


    @TableField("invite_num")
    @Comment("邀请奖励体力")
    @Column(name = "invite_num")
    private long inviteNum;

    @TableField("reward_num")
    @Comment("奖励体力溢出值")
    @Column(name = "reward_num")
    private long rewardNum;


    @TableField("btc_draw_time")
    @Comment("btc签到时间")
    @Column(name = "btc_draw_time")
    private long btcDrawTime;

    @TableField("btc_draw_num")
    @Comment("btc连续签到次数")
    @Column(name = "btc_draw_num")
    private long btcDrawNum;

    @TableField("first_time")
    @Comment("首次签到时间")
    @Column(name = "first_time")
    private LocalDateTime firstTime;

    @TableField("sign_flag")
    @Comment("签到计算标志")
    @Column(name = "sign_flag")
    private long signFlag;

    @TableField("sign_num")
    @Comment("签到次数")
    @Column(name = "sign_num")
    private long signNum;

    @Transient
    @TableField(exist = false)
    private boolean synDb = false;

    public static UserEnergyEntity of(long userId) {
        UserEnergyEntity userEnergyEntity = new UserEnergyEntity();
        userEnergyEntity.setUserId(userId);
        userEnergyEntity.setSynDb(true);
        userEnergyEntity.setCreateTime(LocalDateTime.now());

        return userEnergyEntity;
    }

    public void setSignFlag(long signFlag) {
        this.signFlag = signFlag;
        if (!this.synDb) return;
        SynDBMgr.addChangeData(UserEnergyEntity::getSignFlag, this);
    }

    public void setSignNum(long signNum) {
        this.signNum = signNum;
        if (!this.synDb) return;
        SynDBMgr.addChangeData(UserEnergyEntity::getSignNum, this);
    }

    public void addSignNum() {
        this.signNum += 1;
        this.setSignNum(this.signNum);
    }

    public void setFirstTime(LocalDateTime firstTime) {
        this.firstTime = firstTime;
        if (!this.synDb) return;
        SynDBMgr.addChangeData(UserEnergyEntity::getFirstTime, this);
    }

    public void setBtcDrawNum(long btcDrawNum) {
        this.btcDrawNum = btcDrawNum;
        if (!this.synDb) return;
        SynDBMgr.addChangeData(UserEnergyEntity::getBtcDrawNum, this);
    }

    public void setBtcDrawTime(long btcDrawTime) {
        this.btcDrawTime = btcDrawTime;
        if (!this.synDb) return;
        SynDBMgr.addChangeData(UserEnergyEntity::getBtcDrawTime, this);
    }

    public void addBtcDrawNum() {
        this.btcDrawNum++;
        this.setBtcDrawNum(this.btcDrawNum);
    }

    public void setInviteNum(long inviteNum) {
        this.inviteNum = inviteNum;
        if (!this.synDb) return;
        SynDBMgr.addChangeData(UserEnergyEntity::getInviteNum, this);
    }

    public void addInviteNum(long num) {
        var ret = MathUtil.canAddNum(this.inviteNum, num);
        if (Def.Zero >= ret) return;
        this.setInviteNum(this.inviteNum + ret);
    }

    public void setDrawTime(long drawTime) {
        this.drawTime = drawTime;
        if (!this.synDb) return;
        SynDBMgr.addChangeData(UserEnergyEntity::getDrawTime, this);
    }

    public void setRewardNum(long rewardNum) {
        this.rewardNum = rewardNum;
        if (!this.synDb) return;
        SynDBMgr.addChangeData(UserEnergyEntity::getRewardNum, this);
    }

    public void addRewardNum(long rewardNum) {
        var ret = MathUtil.canAddNum(this.rewardNum, rewardNum);
        if (Def.Zero >= ret) return;
        this.setRewardNum(this.rewardNum + ret);
    }

    public void consumeRewardNum(long rewardNum) {
        if (this.rewardNum < rewardNum) return;
        this.rewardNum -= rewardNum;
        this.setRewardNum(this.rewardNum);
    }

    public void setDrawNum(long drawNum) {
        this.drawNum = drawNum;
        if (!this.synDb) return;
        SynDBMgr.addChangeData(UserEnergyEntity::getDrawNum, this);
    }

    public void addDrawNum() {
        this.drawNum++;
        this.setDrawNum(this.drawNum);
    }

    public void setInit(int init) {
        this.init = init;
        if (!this.synDb) return;
        SynDBMgr.addChangeData(UserEnergyEntity::getInit, this);
    }

    public void setMaxNum(long maxNum) {
        this.maxNum = maxNum;
        if (!this.synDb) return;
        SynDBMgr.addChangeData(UserEnergyEntity::getMaxNum, this);
    }

    public void addMaxNum(long num) {
        this.setMaxNum(this.getMaxNum() + num);
    }

    public void setFlushTime(long flushTime) {
        this.flushTime = flushTime;
        if (!this.synDb) return;
        SynDBMgr.addChangeData(UserEnergyEntity::getFlushTime, this);
    }

    public void setCreateTime(LocalDateTime createTime) {
        this.createTime = createTime;
        if (!this.synDb) return;
        SynDBMgr.addChangeData(UserEnergyEntity::getCreateTime, this);
    }

    public boolean alwaysLogin() {
        if (this.btcDrawTime == Def.Zero) return false;
        //检查今天是否打卡
        return DateUtil.isSameDay(new Date(this.btcDrawTime), SysTimeUtil.getAppDate());
    }
}
